iT邦幫忙

6

[前端/JavaScript] 實作匯出excel下載按鈕的超好用套件:ExcelJS(上)- 基礎介紹與教學

  • 分享至 

  • xImage
  •  

簡介

官方github連結: 英文文檔中文文檔

ExcelJS 這個套件可以高彈性的將資料匯出成excel檔案
(原理:透過套件轉成blob格式,再透過創建URL並觸發來觸發下載)

也可以匯入excel變成json格式的資料

官方文件中提供了相當多操作的介紹,包括設定樣式、插入圖片、對資料做處理等等
接下來介紹的內容,只是會簡單的講解如何將資料匯出成excel檔案(.xslx、.csv)

有時候真的沒有需要那麼華麗
只想要先有一顆可把資料變成excel可供人下載的按鈕

而這個套件本身是透過JS ES6的class來把方法封裝
讓工程師自行使用這些方法來建構你各位想要的excel資料

和按鈕啊、畫面啊、事件綁定之類的沒有關連
這一篇會著重在如何用js去控制你的excel內容

預告:下一篇教學會講解如何在react中使用這個套件

環境建置

  1. 安裝套件 : npm install exceljs --save
  2. 在檔案中 import 套件 import ExcelJs from "exceljs";

開始使用

接下來大致上分三個步驟:建立表格、填塞資料、匯出excel並觸發下載
而這些步驟都是在觸發按下按鈕之後所執行的,也就是說機制與流程是:

按下按鈕
觸發onClick function
在function內建立表格、填塞資料、匯出excel並觸發下載

真的懶得看分解的話
最後面也有簡易的程式碼示範這個onClick function的全貌

那我們先開始分步驟講解這個onClick function內的內容:

1. 建立表格

這個套件匯出的是一個class,並把所有資料操作、設定方法都封裝在class內
所以第一步我們先new出這個class 的實例

const workbook = new ExcelJs.Workbook();

接下來所有操作都會圍繞著這個名稱為 workbook 的物件上

目前的workbook裡面是一個空檔案,裡面沒有任何工作表
所以我們要添加工作表的時候就使用:

const sheet = workbook.addWorksheet('工作表名稱');

工作表名稱可自訂任意type為string的內容
使用addWorksheet 這個方法
會在我們的workbook 物件中增加一個表格,並回傳他的物件

順帶解釋一下,
所謂的「工作表」就是這個下面像是分頁一樣的東西
工作表圖例

一個試算表裡面可以有多個工作表

因此如果要第二個表格就只要繼續使用

const sheet2 = workbook.addWorksheet('工作表2'); 這樣的形式就可以了

2. 填塞資料

在一個工作表內,可以從任意位置開始塞任意大小的資料
將會使用 sheet.addTable 方法 ,參數塞這個表格的資料與格式,
根據columns和rows 這兩個參數提供的陣列(array),在向右和向下的格子裡進行繪製

最基本的範例如下

sheet.addTable({
    name: 'table名稱',  // 表格內看不到的,算是key值,讓你之後想要針對這個table去做額外設定的時候,可以指定到這個table
    ref: 'A1', // 從A1開始
    columns: [{name:'名字'},{name:'年齡'},{name:'電話'}],
    rows: [['小明','20','0987654321'],['小美','23','0912345678']]
});

最基本範例圖

根據這個設定,會跑出來的表格長這樣
在這個addTable傳遞的參數裡面
還可以設置style、設置一些有的沒有的、凍結窗格之類的功能

那些內容有補充在後方,總之我們先創一個最簡單的

  • 進階補充:表格資料可以不止塞一個

    也就是一張sheet中,可以分區塊的於各自指定的位置中,新增多個「table」

    sheet.addTable({
        name: 'table2', 
        ref: 'E5', // 從E5開始
        headerRow: true,  // 有沒有要放標頭那一行 也就是columns的那行資料,如果設為flase就會那行直接無效
        columns: [{name:'欄位1'},{name:'欄位2'},{name:'欄位3'}],
        rows: [['小明','20','0987654321'],['小美','23','0912345678']]
    });
    

    兩個表格

    依此類推可以新增多個
    就不用明明是兩個不一樣的資料表想塞在一個工作表
    硬要想辦法算位置讓他們錯開之類的

3. 匯出excel並觸發下載

在塞完所有的資料之後
使用異步的方法:workbook.xlsx.writeBuffer() 來打包資料
打包好的資料會以Promise 的形式回傳

可以用.then去接收
也可以把整個onClick function標記成async ,然後使用await來接收
接收資料、創建連結、觸發下載的方式如下

// 表格裡面的資料都填寫完成之後,訂出下載的callback function
// 異步的等待他處理完之後,創建url與連結,觸發下載
workbook.xlsx.writeBuffer().then((content) => {
	const link = document.createElement("a");
  const blobData = new Blob([content], {
    type: "application/vnd.ms-excel;charset=utf-8;"
  });
  link.download = '測試的試算表.xlsx';
  link.href = URL.createObjectURL(blobData);
  link.click();
});

整體範例

  • onClick function 定義 (js版本)

    import ExcelJs from "exceljs";
    
      function onClick(){
        const workbook = new ExcelJs.Workbook(); // 創建試算表檔案
        const sheet = workbook.addWorksheet('工作表範例1'); //在檔案中新增工作表 參數放自訂名稱
    
    		sheet.addTable({ // 在工作表裡面指定位置、格式並用columsn與rows屬性填寫內容
    	    name: 'table名稱',  // 表格內看不到的,讓你之後想要針對這個table去做額外設定的時候,可以指定到這個table
    	    ref: 'A1', // 從A1開始
    	    columns: [{name:'名字'},{name:'年齡'},{name:'電話'}],
    	    rows: [['小明','20','0987654321'],['小美','23','0912345678']]
    		});
    
        // 表格裡面的資料都填寫完成之後,訂出下載的callback function
    		// 異步的等待他處理完之後,創建url與連結,觸發下載
    	  workbook.xlsx.writeBuffer().then((content) => {
    		const link = document.createElement("a");
    	    const blobData = new Blob([content], {
    	      type: "application/vnd.ms-excel;charset=utf-8;"
    	    });
    	    link.download = '測試的試算表.xlsx';
    	    link.href = URL.createObjectURL(blobData);
    	    link.click();
    	  });
    	}
    

    其實就是把那些步驟合在一起變成 onClick function

    實際使用就看你使用什麼框架,或原生js、jQuery + html
    繪製一個button ,綁定onClick事件
    使按鈕按下後會進行「建立表格->塞資料->觸發下載」的程序

    這邊提供一個簡易的線上Demo: 下載excel按鈕範例(原生js+html)

    下載之後就會得到這樣的檔案

    成品

進階:設置表格或欄位樣式、以及其他常用的進階功能

這邊不會全部都介紹(真的要全部就去看官方文檔,反正有翻譯...)
只會提出幾個比較實用/常用/簡單的功能,
以及講解到底要怎麼把這些功能設置上去

設置屬性的方式

設置 工作簿/工作表/Table/欄位 的屬性有兩種方式

  • 第一種是在使用workbook.addWorksheet / sheet.addTable 等方法的時候
    用物件的方式把要設定的屬性直接塞到Properties裡面,例如:

    const sheet = workbook.addWorksheet('sheetName',{
    	views: [{showGridLines: false}]
    });
    
    const table = sheet.addTable({
        name: 'table1',
        headerRow: true,
    });
    
  • 第二種則是先取得操縱該物件的變數,再直接對物件的屬性做修改

    取得物件變數的方式,除了儲存addWorksheet / addTable創建時返回的變數之外
    都可以用name或是id的方式 ( 注意: id從1開始不是從0開始 )
    使用getWorksheet / getTable / getColumn /getRow 去尋找/指定,例如

    // 按 name 提取工作表
    const sheet = workbook.getWorksheet('My Sheet');
    // 按 id 提取工作表,得到workbook中第一張添加進去的sheet
    const sheet = workbook.getWorksheet(1);
    
    // 按 name 提取Table
    const table = workbook.getTable('My Table');
    // 按 id 提取Table,得到第一個add進去的table
    const table = workbook.getTable(1);
    
    // 按 name 提取(直)行
    const column = workbook.getColumn('My Column');
    // 按 id 提取行 => 取得第一行 (A)
    const column = workbook.getColumn(1);
    
    // 按 name 提取(橫)列
    const row = workbook.getRow('My Row');
    // 按 id 提取列 => 取得第一列 (1)
    const row = workbook.getRow(1);
    
    // 然後直接對該物件的屬性做賦
    sheet.views = [{showGridLines: false}]
    table.headerRow = true
    

接下來是介紹可以設置的參數們

工作表 (Worksheet) 可設置的參數們

  • 設置樣式 views: Array<{[props: string]: any}>

    views屬性為一個陣列,陣列內可以有多個物件,
    每個物件為{key: value}的型態

    範例:

    sheet.views = [
    	{showGridLines: false},
    	{state: 'frozen', xSplit: 2, ySplit: 3}
    	// 還可以有其他項目
    ]
    

    以下為views中可設定的{ key: value } 們

    • 是否顯示網格 : { showGridLines: boolean }
      預設:true
      若設置為false ⇒ {showGridLines: false}
      表格的網格就會消失,如圖

      去除網格範例

    • 凍結窗格: {state: 'frozen', xSplit: number, ySplit: number }
      xSplit: 要凍結的(直)行數,如果只要凍結列,就填0或是不設置(undefined)
      ySplit: 要凍結的(橫)列數,如果只要凍結行,就填0或是不設置(undefined)

      範例:{state: 'frozen', xSplit: 1, ySplit: 1} 將凍結第一行&第一列

      凍結窗格範例

  • 設置工作表標籤/分頁顏色: properties.tabColor : {argb: string}
    預設:undefined
    可以設置工作表的標籤顏色 必須吃一個key值為argb的物件
    值則為代表0~255的16進位數值共四組

    argb範例

    範例: sheetproperties.tabColor = {argb: 'FF00FF00'} 則會把標籤設為綠色

    效果圖:
    https://ithelp.ithome.com.tw/upload/images/20220324/20135750fn4bbjuad3.png
    可以設置不同顏色真的很可愛

  • 預設欄寬 : properties.defaultColWidth : number
    預設: undefined
    可以設置表格的預設欄寬,範例: sheetproperties.tabColor = 30

    預設欄寬

  • 預設欄高: properties.defaultRowHeight: number
    預設: 15

  • 合併儲存格: worksheet.mergeCells('start:end')
    範例: worksheet.mergeCells('C1:D1')
    合併儲存格範例

  • 針對指定的(直)行設定寬度: sheet.getColumn(number).width
    (其實就是先取得column物件,然後對他的width做賦值)

    範例:sheet.getColumn(3).width = 30
    C行 (第三行)的寬度就會被拉大為30
    https://ithelp.ithome.com.tw/upload/images/20220324/20135750HwMjBP4WFi.png

結語

以上! 希望這一篇可以提供給正在找這個套件教學的各位
下一篇將會示範如何在react中使用這個套件
以及示範將這個按鈕包裝成一個可重複使用的UI元件

[前端/ES6] 實作匯出excel下載按鈕的超好用套件:ExcelJS(下)- 用React匯出excel (export excel)


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
vspeter
iT邦新手 5 級 ‧ 2023-06-05 12:24:15

import ExcelJs from "exceljs"時發生錯誤如何處理

你要先看看有沒有安裝成功exceljs 哦
npm install exceljs --save 看看

或是你要使用CDN也可以?
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js" ></script>

看你的開發環境是什麼

0
applea46
iT邦新手 5 級 ‧ 2023-06-20 09:14:07

請問這套能在ASP環境使用嗎?

我要留言

立即登入留言